﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronOne.SalesOne.BusinessObjects;
using System.Linq.Dynamic;
using System.Configuration;


namespace IronOne.SalesOne.DataObjects
{
    public class LingDeviceMapper
    {
        public int pageSize = Convert.ToInt32(ConfigurationManager.AppSettings["GridCount"]);

        public List<MappingInfo> GetMappingInfo(int branch, int? unit, string so, int pageNo)
        {
            using (SODataDataContext db = DataContextFactory.CreateContext())
            {
                //StringBuilder whereSO = new StringBuilder();
                //whereSO.Append(string.Empty);
                StringBuilder whereUnit = new StringBuilder();
                whereUnit.Append(string.Empty);

                //Expression<Func<UserEntity, Boolean>> predicate = PredicateBuilder.False<UserEntity>();
                var predicate = PredicateBuilder.True<UserEntity>();

                if (so != null)
                    //whereSO.Append("SOCode = \"" + so + "\"");
                    predicate = predicate.And(p => p.SOCode == so);
                                
                whereUnit.Append("BranchId = " + branch);

                if (unit != null)
                {
                    whereUnit.Append(" AND UnitId = " + unit);
                }

                /*var query = from sync in db.SyncInfoEntities
                            join u in db.UserEntities.Where(predicate) on sync.SOCode equals u.SOCode
                            join us in db.UsersInStructureEntities on u.UserId equals us.UserId
                            join un in db.UnitEntities.Where(whereUnit.ToString()) on us.NodeId equals un.UnitId
                            where u.SOCode != null && us.UserTypeId == 4
                            select new MappingInfo
                            {
                                SOCode =  sync.SOCode,
                                DeviceId = sync.DeviceId,
                                SyncDate = sync.Date,
                                SyncStatus = (u.IsSyncBlocked != null && u.IsSyncBlocked == true) ? true : false
                            };*/

                var query = from user in db.UserEntities.Where(predicate)
                            join us in db.UsersInStructureEntities on user.UserId equals us.UserId
                            join un in db.UnitEntities.Where(whereUnit.ToString()) on us.NodeId equals un.UnitId
                            where user.SOCode != null && user.DeviceID != null && us.UserTypeId == 4
                            select new MappingInfo
                            {
                                SOCode = user.SOCode,
                                DeviceId = user.DeviceID,
                                SyncDate = (from sync in db.SyncInfoEntities
                                                where sync.SOCode == user.SOCode && sync.DeviceId == user.DeviceID
                                                select sync.Date).Max(),
                                SyncStatus = (user.IsSyncBlocked != null && user.IsSyncBlocked == true) ? true : false
                            };

                //paging
                var pageData = query.Skip((pageNo - 1) * pageSize).Take(pageSize);

                return pageData.ToList();
            }
        }

        public bool UpdateMappingInfo(MappingInfo info)
        {
            using (SODataDataContext db = DataContextFactory.CreateContext())
            {
                //(from u in db.UserEntities where u.SOCode == info.SOCode select u).Update(d => { d.IsSyncBlocked = info.SyncStatus; });
                UserEntity user = (from u in db.UserEntities 
                            where u.SOCode == info.SOCode 
                            select u).Single();

                user.IsSyncBlocked = info.SyncStatus;

                //db.UserEntities.Attach(user, true);
                try
                {
                    db.SubmitChanges();
                }
                catch
                {
                    return false;
                }
                return true;
            }
        }
    }

    /*public static class UpdateExtensions
    {

        public static void Update<TSource>(this IEnumerable<TSource> source, Func<TSource> update)
        {
            foreach (TSource element in source)
            {
                update(element);
            }
        }

        public delegate void Func<TArg0>(TArg0 element);
    }*/
}